package org.gastomuito.server;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

public class ContaContabil implements Serializable {

    private static final long serialVersionUID = -5140987365250715069L;

    private String nome;

    private Set<EntradaContabil> entradas = new HashSet<EntradaContabil>();

    public ContaContabil() {
    }

    public ContaContabil(String nome) {
        this.nome = nome;
    }

    public void adicionarEntrada(double quantidade, Date quando) {
        adicionarEntrada(new EntradaContabil(quando, quantidade));
    }

    public void adicionarEntrada(EntradaContabil entradaContabil) {
        this.entradas.add(entradaContabil);
    }

    public double balanco(DataIntervalo periodo) {
        double balanco = 0.0;
        for (EntradaContabil entrada : this.entradas) {
            if (periodo.inclui(entrada.getQuando())) {
                balanco += entrada.getQuantidade();
            }
        }
        return balanco;
    }

    public double balanco(Date ate) {
        return balanco(DataIntervalo.ate(ate));
    }

    public double balanco() {
        return balanco(new Date());
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void debitar(double quantidade, ContaContabil destino, Date quando) {
        TransacaoContabil transacao = new TransacaoContabil(quando);
        transacao.adiciona(-quantidade, this, destino.getNome());
        transacao.adiciona(quantidade, destino, this.getNome());
        transacao.processar();
    }

    public Set<EntradaContabil> getEntradas() {
        return this.entradas;
    }

    public double totalPositivo() {
        return totalPositivo(DataIntervalo.ate(new Date()));
    }

    public double totalPositivo(DataIntervalo periodo) {
        double totalPositivo = 0.0;
        for (EntradaContabil entrada : this.entradas) {
            if (periodo.inclui(entrada.getQuando())
                    && entrada.getQuantidade() > 0.0) {
                totalPositivo += entrada.getQuantidade();
            }
        }
        return totalPositivo;
    }

    public double totalNegativo() {
        return totalNegativo(DataIntervalo.ate(new Date()));
    }

    public double totalNegativo(DataIntervalo periodo) {
        double totalPositivo = 0.0;
        for (EntradaContabil entrada : this.entradas) {
            if (periodo.inclui(entrada.getQuando())
                    && entrada.getQuantidade() < 0.0) {
                totalPositivo += -entrada.getQuantidade();
            }
        }
        return totalPositivo;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((nome == null) ? 0 : nome.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ContaContabil other = (ContaContabil) obj;
        if (nome == null) {
            if (other.nome != null)
                return false;
        } else if (!nome.equals(other.nome))
            return false;
        return true;
    }

}
